home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / games_d / gnuchess.zip / NUXDSP.C < prev    next >
Text File  |  1990-07-21  |  38KB  |  1,607 lines

  1. /* nuxdsp.c - (new)  ALPHA interface for CHESS
  2.  
  3.   Revision: 1990-05-09
  4.  
  5.   Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
  6.   Copyright (c) 1988, 1989, 1990  John Stanback
  7.  
  8.   Modified extensively Nov 1989 Christopher North-Keys
  9.     40x24 two-colour display
  10.         option for shading black squares
  11.         expanded game save, list, and restore features using $HOME
  12.         option to disable display of coordinates
  13.         optional auto-updating of positional information
  14.         optional starring of black side
  15.         mass toggle for reverse-video functions
  16.  
  17.   This file is part of CHESS.
  18.  
  19.   CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  20.   WARRANTY.  No author or distributor accepts responsibility to anyone for
  21.   the consequences of using it or for whether it serves any particular
  22.   purpose or works at all, unless he says so in writing.  Refer to the CHESS
  23.   General Public License for full details.
  24.  
  25.   Everyone is granted permission to copy, modify and redistribute CHESS, but
  26.   only under the conditions described in the CHESS General Public License.
  27.   A copy of this license is supposed to have been given to you along with
  28.   CHESS so you can know your rights and responsibilities.  It should be in a
  29.   file named COPYING.  Among other things, the copyright notice and this
  30.   notice must be preserved on all copies.
  31. */
  32.  
  33.  
  34. #include <ctype.h>
  35. #include <signal.h>
  36. #ifdef MSDOS
  37. #include <dos.h>
  38. #include <conio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <time.h>
  42.  
  43. #define ESC 0x1B
  44. #define scanz scanf
  45. #define printz printf
  46. #define refresh() fflush(stdout)
  47.  
  48. int mycntl1, mycntl2;
  49. static void param (short n);
  50. #else
  51. #include <sys/param.h>
  52. #include <sys/types.h>
  53. #include <sys/file.h>
  54. #include <curses.h>
  55.  
  56. #define scanz fflush(stdout),scanw
  57. #define printz printw
  58.  
  59. /* <stdlib.h> */
  60. extern void *malloc (size_t);
  61. extern void exit (int);
  62. /* <string.h> */
  63. extern char *strcat (char *, const char *);
  64. extern int strcmp (const char *, const char *);
  65. extern char *strcpy (char *, const char *);
  66. /* <time.h> */
  67. extern long int time (long int *);
  68. #endif /* MSDOS */
  69.  
  70. #include "gnuchess.h"
  71.  
  72. #define pxx " PNBRQK"
  73. #define qxx " pnbrqk"
  74. #define rxx "12345678"
  75. #define cxx "abcdefgh"
  76. #define TAB (43)
  77. /* coordinates within a square for the following are ([1,5],[1,3]) */
  78. #define SQW (5)
  79. #define SQH (3)
  80. #define VIR_C(s)  ((flag.reverse) ? 7-column(s) : column(s))
  81. #define VIR_R(s)  ((flag.reverse) ? 7-row(s) : row(s))
  82. #define VSQ_X(x)  ((flag.reverse) ? SQW + 1 - (x) : (x))
  83. #define VSQ_Y(y)  ((flag.reverse) ? SQH + 1 - (y) : (y))
  84. #define Vblack(s) (!((VIR_C(s) + VIR_R(s)) % 2))
  85. /* Squares swapped */
  86. #define Vcoord(s,x,y) \
  87.         ((SQW)*(VIR_C(s)))+(x),((SQH)*(7-VIR_R(s))+(y))
  88. /* Squares and internal locations swapped */
  89. #define VcoordI(s,x,y) \
  90.         ((SQW)*(VIR_C(s)))+(VSQ_X(x)),((SQH)*(7-VIR_R(s))+(VSQ_Y(y)))
  91. /* Squares and internal rows swapped */
  92. #define VcoordR(s,x,y) \
  93.         ((SQW)*(VIR_C(s)))+(x),((SQH)*(7-VIR_R(s))+(VSQ_Y(y)))
  94.  
  95. static char mvstr[4][6];
  96. static char* ColorStr[2] = {"White", "Black"};
  97. static long evrate;
  98. short PositionFlag = 0;
  99. short coords = 1;
  100. #if defined(MSDOS) && !defined(SEVENBIT)
  101. short rv = 0;
  102. static void ONormal (void);
  103. static void OReverse (void);
  104. #else
  105. short stars = 0;
  106. short rv = 1;
  107. short shade = 0;
  108. #endif /* MSDOS && !SEVENBIT */
  109. #ifndef __ZTC__
  110. extern char *getenv (const char *);
  111. #endif
  112. void TerminateSearch (int), Die (int);
  113.  
  114. void
  115. Initialize (void)
  116. {
  117.   signal (SIGINT, Die);
  118. #ifndef MSDOS
  119.   signal (SIGQUIT, Die);
  120.   initscr ();
  121.   crmode ();
  122. #else
  123.   mycntl1 = mycntl2 = 0;
  124. #endif /* MSDOS */
  125. }
  126.  
  127. void
  128. ExitChess (void)
  129. {
  130.   ListGame ();
  131.   gotoXY (1, 24);
  132. #ifndef MSDOS
  133.   nocrmode ();
  134.   endwin ();
  135. #endif /* MSDOS */
  136.   exit (0);
  137. }
  138.  
  139. void
  140. Die (int Sig)
  141. {
  142.   char s[80];
  143.  
  144.   signal (SIGINT, SIG_IGN);
  145. #ifdef MSDOS
  146.   Sig++;                                /* shut up the compiler */
  147. #else
  148.   signal (SIGQUIT, SIG_IGN);
  149. #endif /* MSDOS */
  150.   ShowMessage ("Abort? ");
  151.   scanz ("%s", s);
  152.   if (strcmp (s, "yes") == 0)
  153.     ExitChess ();
  154.   signal (SIGINT, Die);
  155. #ifndef MSDOS
  156.   signal (SIGQUIT, Die);
  157. #endif /* MSDOS */
  158. }
  159.  
  160. void
  161. TerminateSearch (int Sig)
  162. {
  163.   signal (SIGINT, SIG_IGN);
  164. #ifdef MSDOS
  165.   Sig++;                                /* shut up the compiler */
  166. #else
  167.   signal (SIGQUIT, SIG_IGN);
  168. #endif /* MSDOS */
  169.   flag.timeout = true;
  170.   flag.bothsides = false;
  171.   signal (SIGINT, Die);
  172. #ifndef MSDOS
  173.   signal (SIGQUIT, Die);
  174. #endif /* MSDOS */
  175. }
  176.  
  177. void
  178. algbr (short int f, short int t, short int flag)
  179.  
  180. /*
  181.    Generate move strings in different formats.
  182. */
  183.  
  184. {
  185.   int m3p;
  186.  
  187.   if (f != t)
  188.     {
  189.       /* algebraic notation */
  190.       mvstr[0][0] = cxx[column (f)];
  191.       mvstr[0][1] = rxx[row (f)];
  192.       mvstr[0][2] = cxx[column (t)];
  193.       mvstr[0][3] = rxx[row (t)];
  194.       mvstr[0][4] = mvstr[3][0] = '\0';
  195.       if ((mvstr[1][0] = pxx[board[f]]) == 'P')
  196.         {
  197.           if (mvstr[0][0] == mvstr[0][2])       /* pawn did not eat */
  198.             {
  199.               mvstr[2][0] = mvstr[1][0] = mvstr[0][2];  /* to column */
  200.               mvstr[2][1] = mvstr[1][1] = mvstr[0][3];  /* to row */
  201.               m3p = 2;
  202.             }
  203.           else
  204.             /* pawn ate */
  205.             {
  206.               mvstr[2][0] = mvstr[1][0] = mvstr[0][0];  /* from column */
  207.               mvstr[2][1] = mvstr[1][1] = mvstr[0][2];  /* to column */
  208.               mvstr[2][2] = mvstr[0][3];
  209.               m3p = 3;          /* to row */
  210.             }
  211.           mvstr[2][m3p] = mvstr[1][2] = '\0';
  212.           if (flag & promote)
  213.             {
  214.               mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  215.               mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
  216.             }
  217.         }
  218.       else
  219.         /* not a pawn */
  220.         {
  221.           mvstr[2][0] = mvstr[1][0];
  222.           mvstr[2][1] = mvstr[0][1];
  223.           mvstr[2][2] = mvstr[1][1] = mvstr[0][2];      /* to column */
  224.           mvstr[2][3] = mvstr[1][2] = mvstr[0][3];      /* to row */
  225.           mvstr[2][4] = mvstr[1][3] = '\0';
  226.           strcpy (mvstr[3], mvstr[2]);
  227.           mvstr[3][1] = mvstr[0][0];
  228.           if (flag & cstlmask)
  229.             {
  230.               if (t > f)
  231.                 {
  232.                   strcpy (mvstr[1], "o-o");
  233.                   strcpy (mvstr[2], "O-O");
  234.                 }
  235.               else
  236.                 {
  237.                   strcpy (mvstr[1], "o-o-o");
  238.                   strcpy (mvstr[2], "O-O-O");
  239.                 }
  240.             }
  241.         }
  242.     }
  243.   else
  244.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  245. }
  246.  
  247. int
  248. VerifyMove (char *s, short int iop, unsigned short int *mv)
  249.  
  250. /*
  251.    Compare the string 's' to the list of legal moves available for the
  252.    opponent. If a match is found, make the move on the board.
  253. */
  254.  
  255. {
  256.   static short pnt, tempb, tempc, tempsf, tempst, cnt;
  257.   static struct leaf xnode;
  258.   struct leaf *node;
  259.  
  260.   *mv = 0;
  261.   if (iop == 2)
  262.     {
  263.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  264.       return (false);
  265.     }
  266.   cnt = 0;
  267.   MoveList (opponent, 2);
  268.   pnt = TrPnt[2];
  269.   while (pnt < TrPnt[3])
  270.     {
  271.       node = &Tree[pnt++];
  272.       algbr (node->f, node->t, (short) node->flags);
  273.       if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
  274.           strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
  275.         {
  276.           cnt++;
  277.           xnode = *node;
  278.         }
  279.     }
  280.   if (cnt == 1)
  281.     {
  282.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, &INCscore);
  283.       if (SqAtakd (PieceList[opponent][0], computer))
  284.         {
  285.           UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  286.           ShowMessage ("Illegal Move!!");
  287.           return (false);
  288.         }
  289.       else
  290.         {
  291.           if (iop == 1)
  292.             return (true);
  293.           UpdateDisplay (xnode.f, xnode.t, 0, (short) xnode.flags);
  294.           if ((board[xnode.t] == pawn)
  295.               || (xnode.flags & capture)
  296.               || (xnode.flags & cstlmask))
  297.             {
  298.               Game50 = GameCnt;
  299.               ZeroRPT ();
  300.             }
  301.           GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  302.           GameList[GameCnt].nodes = 0;
  303.           ElapsedTime (1);
  304.           GameList[GameCnt].time = (short) et;
  305.           TimeControl.clock[opponent] -= et;
  306.           --TimeControl.moves[opponent];
  307.           *mv = (xnode.f << 8) | xnode.t;
  308.           algbr (xnode.f, xnode.t, false);
  309.           return (true);
  310.         }
  311.     }
  312.   if (cnt > 1)
  313.     ShowMessage ("Ambiguous Move!");
  314.   return (false);
  315. }
  316.  
  317. void
  318. help (void)
  319. {
  320.   ClrScreen ();
  321.   printz ("CHESS command summary\n");
  322.   printz ("g1f3     move from g1 to f3      quit      Exit Chess\n");
  323.   printz ("Nf3      move knight to f3       beep      on/off\n");
  324.   printz ("o-o      castle king side        easy      on/off\n");
  325.   printz ("o-o-o    castle queen side       hash      on/off\n");
  326.   printz ("bd       redraw board            reverse   board display\n");
  327.   printz ("list     game to chess.lst       book      on/off\n");
  328.   printz ("undo     undo last ply           remove    take back a move\n");
  329.   printz ("edit     edit board              force     enter game moves\n");
  330.   printz ("switch   sides with computer     both      computer match\n");
  331.   printz ("white    computer plays white    black     computer plays black\n");
  332.   printz ("depth    set search depth        level     select level\n");
  333.   printz ("post     principle variation     hint      suggest a move\n");
  334.   printz ("save     game to file            get       game from file\n");
  335.   printz ("random   randomize play          new       start new game\n");
  336.   printz ("rv       toggle reverse video    coords    toggle coords\n");
  337. #if !defined(MSDOS) || defined(SEVENBIT)
  338.   printz ("shade    toggle shade black      stars     toggle stars\n");
  339. #endif /* !MSDOS || SEVENBIT */
  340.   printz ("p        show coordinate values\n");
  341.   gotoXY (10, 21);
  342.   printz ("Computer: %s", ColorStr[computer]);
  343.   gotoXY (10, 22);
  344.   printz ("Opponent: %s", ColorStr[opponent]);
  345.   gotoXY (10, 23);
  346.   printz ("Level: %ld", Level);
  347.   gotoXY (10, 24);
  348.   printz ("Easy mode: %s", (flag.easy) ? "ON" : "OFF");
  349.   gotoXY (40, 21);
  350.   printz ("Depth: %d", MaxSearchDepth);
  351.   gotoXY (40, 22);
  352.   printz ("Random: %s", (dither) ? "ON" : "OFF");
  353.   gotoXY (40, 23);
  354.   printz ("Transposition table: %s", (flag.hash) ? "ON" : "OFF");
  355.   gotoXY (40, 24);
  356.   printz ("Hit <RET> to return: ");
  357.   refresh ();
  358.   fflush(stdin);
  359.   getchar();
  360.   ClrScreen ();
  361.   UpdateDisplay (0, 0, 1, 0);
  362. }
  363.  
  364. void
  365. EditBoard (void)
  366.  
  367. /*
  368.   Set up a board position. Pieces are entered by typing the piece
  369.   followed by the location. For example, Nf3 will place a knight on
  370.   square f3.
  371. */
  372.  
  373. {
  374.   short a, r, c, sq, i;
  375.   char s[80];
  376.  
  377.   ClrScreen ();
  378.   UpdateDisplay (0, 0, 1, 0);
  379.   gotoXY (TAB, 3);
  380.   printz (".   Exit to main");
  381.   gotoXY (TAB, 4);
  382.   printz ("#   Clear board");
  383.   gotoXY (TAB, 5);
  384.   printz ("c   Change sides");
  385.   gotoXY (TAB, 7);
  386.   printz ("Enter piece & location: ");
  387.   a = white;
  388.   do
  389.     {
  390.       gotoXY (TAB, 6);
  391.       printz ("Editing: %s", ColorStr[a]);
  392.       gotoXY (TAB + 24, 7);
  393.       ClrEoln ();
  394.       scanz ("%s", s);
  395.       if (s[0] == '#')
  396.         {
  397.           for(sq = 0; sq < 64; sq++)
  398.             {
  399.               board[sq] = no_piece;
  400.               color[sq] = neutral;
  401.               DrawPiece (sq);
  402.             }
  403.         }
  404.       if (s[0] == 'c' || s[0] == 'C')
  405.         a = otherside[a];
  406.       c = s[1] - 'a';
  407.       r = s[2] - '1';
  408.       if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
  409.         {
  410.           sq = locn (r, c);
  411.           for (i = king; i > no_piece; i--)
  412.             if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
  413.               break;
  414.           board[sq] = i;
  415.           color[sq] = (board[sq] == no_piece) ? neutral : a;
  416.           DrawPiece (sq);
  417.         }
  418.   } while (s[0] != '.');
  419.  
  420.   for (sq = 0; sq < 64; sq++)
  421.     Mvboard[sq] = (board[sq] != Stboard[sq]) ? 10 : 0;
  422.   GameCnt = 0;
  423.   Game50 = 1;
  424.   ZeroRPT ();
  425.   Sdepth = 0;
  426.   InitializeStats ();
  427.   ClrScreen ();
  428.   UpdateDisplay (0, 0, 1, 0);
  429. }
  430.  
  431. void
  432. ShowPlayers (void)
  433. {
  434.   gotoXY (TAB, ((flag.reverse) ? 23 : 2));
  435.   printz ("%s", (computer == black) ? "Computer" : "Human   ");
  436.   gotoXY (TAB, ((flag.reverse) ? 2 : 23));
  437.   printz ("%s", (computer == white) ? "Computer" : "Human   ");
  438. }
  439.  
  440. void
  441. ShowDepth (char ch)
  442. {
  443.   gotoXY (TAB, 4);
  444.   printz ("Depth= %d%c ", Sdepth, ch);
  445.   ClrEoln ();
  446. }
  447.  
  448. void
  449. ShowScore (short score)
  450. {
  451.   gotoXY (TAB, 5);
  452.   printz ("Score= %d", score);
  453.   ClrEoln ();
  454. }
  455.  
  456. void
  457. ShowMessage (char *s)
  458. {
  459.   gotoXY (TAB, 6);
  460.   printz ("%s", s);
  461.   ClrEoln ();
  462. }
  463.  
  464. void
  465. ClearMessage (void)
  466. {
  467.   gotoXY (TAB, 6);
  468.   ClrEoln ();
  469. }
  470.  
  471. void
  472. ShowCurrentMove (short int pnt, short int f, short int t)
  473. {
  474.   algbr (f, t, false);
  475.   gotoXY (TAB, 7);
  476.   printz ("(%2d) %4s", pnt, mvstr[0]);
  477. }
  478.  
  479. void
  480. ShowHeader (void)
  481. {
  482.   gotoXY (TAB, 10);
  483. #ifdef MSDOS
  484.   printz ("GNU Chess display (MS-DOS, Mar 90)");
  485. #else
  486.   printz ("GNU Chess display (Nov 89)");
  487. #endif /* MSDOS */
  488. }
  489.  
  490. void
  491. ShowSidetomove (void)
  492. {
  493.   gotoXY (TAB, 14);
  494.   printz ("%2d:   %s", 1 + GameCnt / 2, ColorStr[player]);
  495.   ClrEoln ();
  496. }
  497.  
  498. void
  499. ShowPrompt (void)
  500. {
  501.   gotoXY (TAB, 19);
  502.   printz ("Your move is? ");
  503.   ClrEoln ();
  504. }
  505.  
  506. void
  507. ShowNodeCnt (long int NodeCnt, long int evrate)
  508. {
  509.   gotoXY (TAB, 21);
  510.   printz ("Nodes= %8ld, Nodes/Sec= %5ld", NodeCnt, evrate);
  511.   ClrEoln ();
  512. }
  513.  
  514. void
  515. ShowResults (short int score, unsigned short int *bstline, char ch)
  516. {
  517.   unsigned char d, ply;
  518.   if (flag.post)
  519.     {
  520.       ShowDepth (ch);
  521.       ShowScore (score);
  522.       d = 7;
  523.       for (ply = 1; bstline[ply] > 0; ply++)
  524.         {
  525.           if (ply % 4 == 1)
  526.             {
  527.               gotoXY (TAB, ++d);
  528.               ClrEoln ();
  529.             }
  530.           algbr ((short) bstline[ply] >> 8, (short) bstline[ply] & 0xFF, false);
  531.           printz ("%5s ", mvstr[0]);
  532.         }
  533.       ClrEoln ();
  534.       while (d < 13)
  535.         {
  536.           gotoXY (TAB, ++d);
  537.           ClrEoln ();
  538.         }
  539.     }
  540. }
  541.  
  542. void
  543. SearchStartStuff (short int side)
  544. {
  545.   short i;
  546.  
  547.   signal (SIGINT, TerminateSearch);
  548. #ifdef MSDOS
  549.   side++;                               /* shut up the compiler */
  550. #else
  551.   signal (SIGQUIT, TerminateSearch);
  552. #endif /* MSDOS */
  553.   for (i = 4; i < 14; i++)
  554.     {
  555.       gotoXY (TAB, i);
  556.       ClrEoln ();
  557.     }
  558. }
  559.  
  560. void
  561. OutputMove (void)
  562. {
  563.   int i;
  564.  
  565.   UpdateDisplay (root->f, root->t, 0, (short) root->flags);
  566.   gotoXY (TAB, 17);
  567.   printz ("My move is: %s", mvstr[0]);
  568.   if (flag.beep)
  569.     putchar (7);
  570.   ClrEoln ();
  571.  
  572.   gotoXY (TAB, 24);
  573.   if (root->flags & draw)
  574.     printz ("Drawn game!");
  575.   else if (root->score == -9999)
  576.     printz ("Opponent mates!");
  577.   else if (root->score == 9998)
  578.     printz ("Computer mates!");
  579.   else if (root->score < -9000)
  580.     printz ("Opponent will soon mate!");
  581.   else if (root->score > 9000)
  582.     printz ("Computer will soon mate!");
  583.   ClrEoln ();
  584.  
  585.   if (flag.post)
  586.     {
  587.       ShowNodeCnt (NodeCnt, evrate);
  588.       gotoXY (TAB, 22);
  589.       for (i = 1999; i >= 0 && Tree[i].f == 0 && Tree[i].t == 0; i--) ;
  590.       printz ("Max Tree= %5d", i);
  591.       ClrEoln ();
  592.     }
  593. }
  594.  
  595. void
  596. ElapsedTime (short int iop)
  597.  
  598. /*
  599.   Determine the time that has passed since the search was started. If
  600.   the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
  601.   timeout to true which will terminate the search.
  602. */
  603.  
  604. {
  605.   et = time ((long *) 0) - time0;
  606.   if (et < 0)
  607.     et = 0;
  608.   ETnodes += 50;
  609.   if (et > et0 || iop == 1)
  610.     {
  611.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  612.         flag.timeout = true;
  613.       et0 = et;
  614.       if (iop == 1)
  615.         {
  616.           time0 = time ((long *) 0);
  617.           et0 = 0;
  618.         }
  619.       if (et > 0)
  620.         /* evrate used to be Nodes / cputime I dont` know why */
  621.         evrate = NodeCnt / (et + ft);
  622.       else
  623.         evrate = 0;
  624.       ETnodes = NodeCnt + 50;
  625.       UpdateClocks ();
  626.     }
  627. }
  628.  
  629. void
  630. UpdateClocks (void)
  631. {
  632.   short m, s;
  633.   m = (short) (et / 60);
  634.   s = (short) (et - 60 * (long) m);
  635.   if (TCflag)
  636.     {
  637.       m = (short) ((TimeControl.clock[player] - et) / 60);
  638.       s = (short) (TimeControl.clock[player] - et - 60 * (long) m);
  639.     }
  640.   if (m < 0)
  641.     m = 0;
  642.   if (s < 0)
  643.     s = 0;
  644.   if (player == white)
  645.     gotoXY (60, (flag.reverse) ? 2 : 23);
  646.   else
  647.     gotoXY (60, (flag.reverse) ? 23 : 2);
  648.   printz ("%d:%2d   ", m, s);
  649.   if (flag.post)
  650.     ShowNodeCnt (NodeCnt, evrate);
  651.   refresh ();
  652. }
  653.  
  654.  
  655. void
  656. SetTimeControl (void)
  657. {
  658.   if (TCflag)
  659.     {
  660.       TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
  661.       TimeControl.clock[white] = TimeControl.clock[black] = 60 * (long) TCminutes;
  662.     }
  663.   else
  664.     {
  665.       TimeControl.moves[white] = TimeControl.moves[black] = 0;
  666.       TimeControl.clock[white] = TimeControl.clock[black] = 0;
  667.       Level = 60 * (long) TCminutes;
  668.     }
  669.   et = 0;
  670.   ElapsedTime (1);
  671. }
  672.  
  673. void
  674. gotoXY (short int x, short int y)
  675. {
  676. #ifdef MSDOS
  677.   putchar(ESC);
  678.   putchar('[');
  679.   param(y);
  680.   putchar(';');
  681.   param(x);
  682.   putchar('H');
  683. #else
  684.   move (y - 1, x - 1);
  685. #endif /* MSDOS */
  686. }
  687.  
  688. void
  689. ClrScreen (void)
  690. {
  691. #ifdef MSDOS
  692.   putchar(ESC);
  693.   putchar('[');
  694.   putchar('2');
  695.   putchar('J');
  696. #else
  697.   clear ();
  698. #endif /* MSDOS */
  699.   refresh ();
  700. }
  701.  
  702. void
  703. ClrEoln (void)
  704. {
  705. #ifdef MSDOS
  706.   putchar(ESC);
  707.   putchar('[');
  708.   putchar('K');
  709. #else
  710.   clrtoeol ();
  711. #endif /* MSDOS */
  712.   refresh ();
  713. }
  714.  
  715. #ifdef MSDOS
  716. void
  717. param(short n)
  718. {
  719.   if (n >= 10)
  720.     {
  721.     register short d, q;
  722.     q = n/10; d = n%10;
  723.     putchar(q + '0');
  724.     putchar(d + '0');
  725.   }
  726.   else
  727.     putchar(n + '0');
  728. }
  729. #endif /* MSDOS */
  730.  
  731. void
  732. OReverse()
  733. {
  734. #ifdef MSDOS
  735.   putchar (ESC);
  736.   putchar ('[');
  737.   param (7);
  738.   putchar ('m');
  739. #else
  740.   standout ();
  741. /* attron (A_REVERSE); */
  742. #endif /* MSDOS */
  743. }
  744.  
  745. void
  746. ONormal()
  747. {
  748. #ifdef MSDOS
  749.   putchar (ESC);
  750.   putchar ('[');
  751.   param (0);
  752.   putchar ('m');
  753. #else
  754.   standend ();
  755. /* attroff (A_REVERSE);*/
  756. #endif /* MSDOS */
  757. }
  758.  
  759. void
  760. DrawPiece (short int sq)
  761. {
  762.   gotoXY (VcoordR (sq, 2, 2));
  763.  
  764.   switch (color[sq])
  765.     {
  766.     case black:
  767.       if (rv)
  768.         OReverse ();
  769. #if defined(MSDOS) && !defined(SEVENBIT)
  770.       printz (" %c ", pxx[board[sq]]);
  771. #else
  772.       printz ((stars ? "*%c*" : " %c "), pxx[board[sq]]);
  773. #endif /* MSDOS && !SEVENBIT */
  774.       ONormal ();
  775.       break;
  776.     case neutral:
  777. #if defined(MSDOS) && !defined(SEVENBIT)
  778.       if (rv)
  779.         printz (Vblack (sq) ? "\262\262\262" : "\260\260\260");
  780.       else
  781.         printz (Vblack (sq) ? "\260\260\260" : "\262\262\262");
  782. #else
  783.       if (shade)
  784.         printz (Vblack (sq) ? "///" : "   ");
  785.       else
  786.         {
  787.           if (Vblack (sq))
  788.             OReverse ();
  789.           printz ("   ");
  790.           ONormal ();
  791.         }
  792. #endif /* MSDOS && !SEVENBIT */
  793.       break;
  794.     case white:
  795. #if defined(MSDOS) && !defined(SEVENBIT)
  796.       if (!rv)
  797.         OReverse ();
  798.       printz (" %c ", pxx[board[sq]]);
  799.       ONormal ();
  800. #else
  801.       printz (" %c ", pxx[board[sq]]);
  802. #endif /* MSDOS && !SEVENBIT */
  803.       break;
  804.     default:
  805.       ShowMessage ("DrawPiece:  color[sq] err");
  806.       break;
  807.     }
  808. }
  809.  
  810. void
  811. DrawSquare (short int sq)
  812. {
  813. #if defined(MSDOS) && !defined(SEVENBIT)
  814.   if (rv)
  815.     {
  816.       gotoXY (Vcoord (sq, 1, 1));
  817.       printz (Vblack (sq) ? "\262\262\262\262\262" : "\260\260\260\260\260");
  818.       gotoXY (Vcoord (sq, 1, 2));
  819.       printz (Vblack (sq) ? "\262\262\262\262\262" : "\260\260\260\260\260");
  820.       gotoXY (Vcoord (sq, 1, 3));
  821.       printz (Vblack (sq) ? "\262\262\262\262\262" : "\260\260\260\260\260");
  822.     }
  823.   else
  824.     {
  825.       gotoXY (Vcoord (sq, 1, 1));
  826.       printz (Vblack (sq) ? "\260\260\260\260\260" : "\262\262\262\262\262");
  827.       gotoXY (Vcoord (sq, 1, 2));
  828.       printz (Vblack (sq) ? "\260\260\260\260\260" : "\262\262\262\262\262");
  829.       gotoXY (Vcoord (sq, 1, 3));
  830.       printz (Vblack (sq) ? "\260\260\260\260\260" : "\262\262\262\262\262");
  831.     }
  832. #else
  833.   if (shade)
  834.     {
  835.       gotoXY (Vcoord (sq, 1, 1));
  836.       printz (Vblack (sq) ? "/////" : "     ");
  837.       gotoXY (Vcoord (sq, 1, 2));
  838.       printz (Vblack (sq) ? "/////" : "     ");
  839.       gotoXY (Vcoord (sq, 1, 3));
  840.       printz (Vblack (sq) ? "/////" : "     ");
  841.     }
  842.   else
  843.     {
  844.       if (Vblack (sq))
  845.         OReverse ();
  846.       gotoXY (Vcoord (sq, 1, 1));
  847.       printz ("     ");
  848.       gotoXY (Vcoord (sq, 1, 2));
  849.       printz ("     ");
  850.       gotoXY (Vcoord (sq, 1, 3));
  851.       printz ("     ");
  852.       ONormal ();
  853.     }
  854. #endif /* MSDOS && !SEVENBIT */
  855. }
  856.  
  857. void
  858. DrawCoords (void)
  859. {
  860.   short z;
  861.  
  862.   for (z = 0; z <= 7; z++)
  863.     {
  864.       short sq;
  865.  
  866.       sq = z << 3;
  867.       gotoXY (VcoordI (sq, 1, 1));
  868. #if !defined(MSDOS) || defined(SEVENBIT)
  869.       if ((Vblack (sq) || shade) && rv)
  870. #endif /* !MSDOS || SEVENBIT */
  871.         OReverse ();
  872.       printz ("%d", 1 + z);
  873.       ONormal ();
  874.     }
  875.  
  876.   for (z = 0; z <= 7; z++)
  877.     {
  878.       short sq;
  879.  
  880.       sq = z;
  881.       gotoXY (VcoordI (sq, SQW, SQH));
  882. #if !defined(MSDOS) || defined(SEVENBIT)
  883.       if ((Vblack (sq) || shade) && rv)
  884. #endif /* !MSDOS || SEVENBIT */
  885.         OReverse ();
  886.       printz ("%c", cxx[z]);
  887.       ONormal ();
  888.     }
  889.  
  890. #if !defined(MSDOS) || defined(SEVENBIT)
  891.   for (z = 1; z <= (8 * SQH); z++)
  892.     {
  893.       gotoXY ((8 * SQW) + 1, z);
  894.       printz ("|");
  895.     }
  896. #endif /* MSDOS && !SEVENBIT */
  897. }
  898.  
  899. void
  900. ShowPostnValue (short int sq)
  901.  
  902. /*
  903.   must have called ExaminePosition() first
  904. */
  905.  
  906. {
  907.   short score;
  908.  
  909.   gotoXY (VcoordR (sq, 2, 1));
  910.   ScorePosition (color[sq], &score);
  911. #if !defined(MSDOS) || defined(SEVENBIT)
  912.   if (Vblack (sq) && !shade)
  913.     OReverse ();
  914. #endif /* !MSDOS || SEVENBIT */
  915.  
  916.   if (color[sq] != neutral)
  917.     printz ("%3d", svalue[sq]);
  918.   else
  919. #if defined(MSDOS) && !defined(SEVENBIT)
  920.     {
  921.       if (rv)
  922.         printz (Vblack (sq) ? "\262\262\262" : "\260\260\260");
  923.       else
  924.         printz (Vblack (sq) ? "\260\260\260" : "\262\262\262");
  925.     }
  926. #else
  927.     printz (shade && Vblack (sq) ? "///" : "   ");
  928. #endif /* MSDOS && !SEVENBIT */
  929.   ONormal ();
  930. }
  931.  
  932. void
  933. ShowPostnValues (void)
  934. {
  935.   short sq, score;
  936.  
  937.   ExaminePosition ();
  938.   for (sq = 0; sq < 64; sq++)
  939.     ShowPostnValue (sq);
  940.   ScorePosition (opponent, &score);
  941.   ShowScore (score);
  942. }
  943.  
  944. void
  945. UpdateDisplay (short int f, short int t, short int redraw, short int isspec)
  946. {
  947.   short sq;
  948.  
  949.   if (redraw)
  950.     {
  951.       ShowHeader ();
  952.       ShowPlayers ();
  953.       for (sq = 0; sq < 64; sq++)
  954.         {
  955.           DrawSquare (sq);
  956.           DrawPiece (sq);
  957.         }
  958.       if (coords)
  959.         DrawCoords ();
  960.     }
  961.   else
  962.     {
  963.       DrawPiece (f);
  964.       DrawPiece (t);
  965.       if (isspec & cstlmask)
  966.         if (t > f)
  967.           {
  968.             DrawPiece (f + 3);
  969.             DrawPiece (t - 1);
  970.           }
  971.         else
  972.           {
  973.             DrawPiece (f - 4);
  974.             DrawPiece (t + 1);
  975.           }
  976.       else if (isspec & epmask)
  977.         {
  978.           DrawPiece (t - 8);
  979.           DrawPiece (t + 8);
  980.         }
  981.     }
  982.   if (PositionFlag)
  983.     ShowPostnValues ();
  984.   refresh ();
  985. }
  986.  
  987. void
  988. GetGame (void)
  989. {
  990.   FILE *fd;
  991.   char fname[256], tname[256];
  992.   char *tmp;
  993.   int c;
  994.   short sq;
  995.   unsigned short m;
  996.  
  997.   tname[0] = 0;
  998.  
  999.   if ((tmp = getenv ("HOME")) != 0)
  1000.     strcpy (fname, tmp);
  1001.   else
  1002.     fname[0] = '\0';
  1003.   strcat (fname, "/");
  1004.  
  1005.   ShowMessage ("File name: ");
  1006.   scanz ("%s", tname);
  1007.  
  1008.   if (tname[0])
  1009.     strcat (fname, tname);
  1010.   else
  1011.     strcat (fname, "chess.000");
  1012.  
  1013.   ShowMessage("Loading ");
  1014.   printz ("%s", fname);
  1015.  
  1016.   if ((fd = fopen (fname, "r")) == NULL)
  1017.     {
  1018.       ShowMessage ("Load failed");
  1019.       return;
  1020.     }
  1021.  
  1022.   fscanf (fd, "%hd%hd%hd", &computer, &opponent, &Game50);
  1023.   fscanf (fd, "%hd%hd", &castld[white], &castld[black]);
  1024.   fscanf (fd, "%hd%hd", &TCflag, &OperatorTime);
  1025.   fscanf (fd, "%ld%ld%hd%hd",
  1026.           &TimeControl.clock[white], &TimeControl.clock[black],
  1027.           &TimeControl.moves[white], &TimeControl.moves[black]);
  1028.   for (sq = 0; sq < 64; sq++)
  1029.     {
  1030.       fscanf (fd, "%hd%hd", &m, &Mvboard[sq]);
  1031.       board[sq] = (m >> 8);
  1032.       color[sq] = (m & 0xFF);
  1033.       if (color[sq] == 0)
  1034.         color[sq] = neutral;
  1035.       else
  1036.         --color[sq];
  1037.     }
  1038.   GameCnt = 0;
  1039.   c = '?';
  1040.   while (c != EOF)
  1041.     {
  1042.       ++GameCnt;
  1043.       c = fscanf (fd, "%hd%hd%hd%ld%hd%hd%hd", &GameList[GameCnt].gmove,
  1044.                   &GameList[GameCnt].score, &GameList[GameCnt].depth,
  1045.                   &GameList[GameCnt].nodes, &GameList[GameCnt].time,
  1046.                   &GameList[GameCnt].piece, &GameList[GameCnt].color);
  1047.       if (GameList[GameCnt].color == 0)
  1048.         GameList[GameCnt].color = neutral;
  1049.       else
  1050.         --GameList[GameCnt].color;
  1051.     }
  1052.   GameCnt--;
  1053.   if (TimeControl.clock[white] > 0)
  1054.     TCflag = true;
  1055.   computer--;
  1056.   opponent--;
  1057.  
  1058.   fclose (fd);
  1059.  
  1060.   InitializeStats ();
  1061.   Sdepth = 0;
  1062.   ShowMessage ("Load done.  Press <Ret>");
  1063.   fflush (stdin);
  1064.   getchar ();
  1065.   UpdateDisplay (0, 0, 1, 0);
  1066.  
  1067. }
  1068.  
  1069. void
  1070. SaveGame (void)
  1071. {
  1072.   FILE *fd;
  1073.   char fname[256], tname[256];
  1074.   char *tmp;
  1075.   short sq, i, c;
  1076.  
  1077.   tname[0] = 0;
  1078.  
  1079.   if ((tmp = getenv ("HOME")) != 0)
  1080.     strcpy (fname, tmp);
  1081.   else
  1082.     fname[0] = '\0';
  1083.   strcat (fname, "/");
  1084.  
  1085.   ShowMessage ("File name: ");
  1086.   refresh ();
  1087.   scanz ("%s", tname);
  1088.  
  1089.   if (tname[0])
  1090.     strcat (fname, tname);
  1091.   else
  1092.     strcat (fname, "chess.000");
  1093.  
  1094.   ShowMessage("Saving ");
  1095.   printz ("%s", fname);
  1096.  
  1097.   if (NULL == (fd = fopen (fname, "w")))
  1098.     {
  1099.       ShowMessage ("Not saved");
  1100.       return;
  1101.     }
  1102.  
  1103.   fprintf (fd, "%d %d %d\n", computer + 1, opponent + 1, Game50);
  1104.   fprintf (fd, "%d %d\n", castld[white], castld[black]);
  1105.   fprintf (fd, "%d %d\n", TCflag, OperatorTime);
  1106.   fprintf (fd, "%ld %ld %d %d\n",
  1107.            TimeControl.clock[white], TimeControl.clock[black],
  1108.            TimeControl.moves[white], TimeControl.moves[black]);
  1109.   for (sq = 0; sq < 64; sq++)
  1110.     {
  1111.       if (color[sq] == neutral)
  1112.         c = 0;
  1113.       else
  1114.         c = color[sq] + 1;
  1115.       fprintf (fd, "%d %d\n", 256 * board[sq] + c, Mvboard[sq]);
  1116.     }
  1117.   for (i = 1; i <= GameCnt; i++)
  1118.     {
  1119.       if (GameList[i].color == neutral)
  1120.         c = 0;
  1121.       else
  1122.         c = GameList[i].color + 1;
  1123.       fprintf (fd, "%d %d %d %ld %d %d %d\n",
  1124.                GameList[i].gmove, GameList[i].score, GameList[i].depth,
  1125.                GameList[i].nodes, GameList[i].time,
  1126.                GameList[i].piece, c);
  1127.     }
  1128.   fclose (fd);
  1129.   ShowMessage ("Save done.  Press <Ret>");
  1130.   fflush (stdin);
  1131.   getchar ();
  1132. }
  1133.  
  1134. void
  1135. ListGame (void)
  1136. {
  1137.   FILE *fd;
  1138.   char fname[256];
  1139.   char *tmp;
  1140.   short i, f, t;
  1141.  
  1142.   if ((tmp = getenv ("HOME")) != 0)
  1143.     strcpy (fname, tmp);
  1144.   else
  1145.     fname[0] = '\0';
  1146.   strcat (fname, "/chess.lst");
  1147.  
  1148.   if ((fd = fopen (fname, "w")) != 0)
  1149.     ShowMessage ("Writing ~/chess.lst");
  1150.   else
  1151.     {
  1152.       ShowMessage ("Cannot write ~/chess.lst");
  1153.       return;
  1154.     }
  1155.  
  1156.   fprintf (fd, "\n");
  1157.   fprintf (fd, "       score  depth   nodes  time         ");
  1158.   fprintf (fd, "       score  depth   nodes  time\n");
  1159.   for (i = 1; i <= GameCnt; i++)
  1160.     {
  1161.       f = GameList[i].gmove >> 8;
  1162.       t = (GameList[i].gmove & 0xFF);
  1163.       algbr (f, t, false);
  1164.       if ((i % 2) == 0)
  1165.         fprintf (fd, "\n");
  1166.       else
  1167.         fprintf (fd, "         ");
  1168.       fprintf (fd, "%5s  %5d     %2d %7ld %5d", mvstr[0],
  1169.                GameList[i].score, GameList[i].depth,
  1170.                GameList[i].nodes, GameList[i].time);
  1171.     }
  1172.   fprintf (fd, "\n\n");
  1173.   fclose (fd);
  1174.   ShowMessage ("~/chess.lst written");
  1175. }
  1176.  
  1177. void
  1178. Undo (void)
  1179.  
  1180. /*
  1181.   Undo the most recent half-move.
  1182. */
  1183.  
  1184. {
  1185.   short f, t;
  1186.   f = GameList[GameCnt].gmove >> 8;
  1187.   t = GameList[GameCnt].gmove & 0xFF;
  1188.   if (board[t] == king && distance (t, f) > 1)
  1189.     (void) castle (GameList[GameCnt].color, f, t, 2);
  1190.   else
  1191.     {
  1192.       /* Check for promotion: */
  1193.       if ((color[t] == white && row (f) == 6 && row (t) == 7)
  1194.           || (color[t] == black && row (f) == 1 && row (t) == 0))
  1195.         {
  1196.           int g, from = f;
  1197.           for (g = GameCnt - 1; g > 0; g--)
  1198.             if (GameList[g].gmove & 0xFF == from)
  1199.               from = GameList[g].gmove >> 8;
  1200.           if ((color[t] == white && row (from) == 1)
  1201.               || (color[t] == black && row (from) == 6))
  1202.             board[t] = pawn;
  1203.         }
  1204.       board[f] = board[t];
  1205.       color[f] = color[t];
  1206.       board[t] = GameList[GameCnt].piece;
  1207.       color[t] = GameList[GameCnt].color;
  1208.       if (color[t] != neutral)
  1209.         Mvboard[t]--;
  1210.       Mvboard[f]--;
  1211.     }
  1212.   if (TCflag)
  1213.     ++TimeControl.moves[color[f]];
  1214.   GameCnt--;
  1215.   computer = otherside[computer];
  1216.   opponent = otherside[opponent];
  1217.   flag.mate = false;
  1218.   Sdepth = 0;
  1219.   UpdateDisplay (0, 0, 1, 0);
  1220.   InitializeStats ();
  1221. }
  1222.  
  1223. void
  1224. ChangeAlphaWindow (void)
  1225. {
  1226.   ShowMessage ("Awindow= ");
  1227.   scanz ("%hd", &Awindow);
  1228. }
  1229.  
  1230. void
  1231. ChangeBetaWindow (void)
  1232. {
  1233.   ShowMessage ("Bwindow= ");
  1234.   scanz ("%hd", &Bwindow);
  1235. }
  1236.  
  1237. void
  1238. GiveHint (void)
  1239. {
  1240.   char s[40];
  1241.   algbr ((short) (hint >> 8), (short) (hint & 0xFF), false);
  1242.   strcpy (s, "try ");
  1243.   strcat (s, mvstr[0]);
  1244.   ShowMessage (s);
  1245. }
  1246.  
  1247. void
  1248. ChangeSearchDepth (void)
  1249. {
  1250.   ShowMessage ("depth= ");
  1251.   scanz ("%hd", &MaxSearchDepth);
  1252. }
  1253.  
  1254. void
  1255. SetContempt (void)
  1256. {
  1257.   ShowMessage ("contempt= ");
  1258.   scanz ("%hd", &contempt);
  1259. }
  1260.  
  1261. void
  1262. ChangeXwindow (void)
  1263. {
  1264.   ShowMessage ("xwndw= ");
  1265.   scanz ("%hd", &xwndw);
  1266. }
  1267.  
  1268. void
  1269. SelectLevel (void)
  1270. {
  1271.   ClrScreen ();
  1272.   gotoXY (32, 2);
  1273.   printz ("CHESS");
  1274.   gotoXY (20, 4);
  1275.   printz (" 1.   60 moves in   5 minutes");
  1276.   gotoXY (20, 5);
  1277.   printz (" 2.   60 moves in  15 minutes");
  1278.   gotoXY (20, 6);
  1279.   printz (" 3.   60 moves in  30 minutes");
  1280.   gotoXY (20, 7);
  1281.   printz (" 4.   40 moves in  30 minutes");
  1282.   gotoXY (20, 8);
  1283.   printz (" 5.   40 moves in  60 minutes");
  1284.   gotoXY (20, 9);
  1285.   printz (" 6.   40 moves in 120 minutes");
  1286.   gotoXY (20, 10);
  1287.   printz (" 7.   40 moves in 240 minutes");
  1288.   gotoXY (20, 11);
  1289.   printz (" 8.    1 move  in  15 minutes");
  1290.   gotoXY (20, 12);
  1291.   printz (" 9.    1 move  in  60 minutes");
  1292.   gotoXY (20, 13);
  1293.   printz ("10.    1 move  in 600 minutes");
  1294.  
  1295.   OperatorTime = 1;
  1296.   TCmoves = 60;
  1297.   TCminutes = 5;
  1298.  
  1299.   gotoXY (20, 17);
  1300.   printz ("Enter Level: ");
  1301.   refresh ();
  1302.   scanz ("%ld", &Level);
  1303.   switch ((int) Level)
  1304.     {
  1305.     case 1:
  1306.       TCmoves = 60;
  1307.       TCminutes = 5;
  1308.       break;
  1309.     case 2:
  1310.       TCmoves = 60;
  1311.       TCminutes = 15;
  1312.       break;
  1313.     case 3:
  1314.       TCmoves = 60;
  1315.       TCminutes = 30;
  1316.       break;
  1317.     case 4:
  1318.       TCmoves = 40;
  1319.       TCminutes = 30;
  1320.       break;
  1321.     case 5:
  1322.       TCmoves = 40;
  1323.       TCminutes = 60;
  1324.       break;
  1325.     case 6:
  1326.       TCmoves = 40;
  1327.       TCminutes = 120;
  1328.       break;
  1329.     case 7:
  1330.       TCmoves = 40;
  1331.       TCminutes = 240;
  1332.       break;
  1333.     case 8:
  1334.       TCmoves = 1;
  1335.       TCminutes = 15;
  1336.       break;
  1337.     case 9:
  1338.       TCmoves = 1;
  1339.       TCminutes = 60;
  1340.       break;
  1341.     case 10:
  1342.       TCmoves = 1;
  1343.       TCminutes = 600;
  1344.       break;
  1345.     }
  1346.  
  1347.   TCflag = (TCmoves > 1);
  1348.   SetTimeControl ();
  1349.   ClrScreen ();
  1350.   UpdateDisplay (0, 0, 1, 0);
  1351. }
  1352.  
  1353. void
  1354. DoDebug (void)
  1355. {
  1356.   short c, p, sq, tp, tc, tsq, score;
  1357.   char s[40];
  1358.  
  1359.   ExaminePosition ();
  1360.   ShowMessage ("Enter piece: ");
  1361.   scanz ("%s", s);
  1362.   c = neutral;
  1363.   if (s[0] == 'w' || s[0] == 'W')
  1364.     c = white;
  1365.   if (s[0] == 'b' || s[0] == 'B')
  1366.     c = black;
  1367.   for(p = king; p > no_piece; p--)
  1368.     if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
  1369.       break;
  1370.   for (sq = 0; sq < 64; sq++)
  1371.     {
  1372.       tp = board[sq];
  1373.       tc = color[sq];
  1374.       board[sq] = p;
  1375.       color[sq] = c;
  1376.       tsq = PieceList[c][1];
  1377.       PieceList[c][1] = sq;
  1378.       ShowPostnValue (sq);
  1379.       PieceList[c][1] = tsq;
  1380.       board[sq] = tp;
  1381.       color[sq] = tc;
  1382.     }
  1383.   ScorePosition (opponent, &score);
  1384.   ShowScore (score);
  1385. }
  1386.  
  1387. void
  1388. TestSpeed(void (*f) (short int side, short int ply))
  1389. {
  1390.   short i;
  1391.   long t1, t2;
  1392.  
  1393.   t1 = time (0);
  1394.   for (i = 0; i < 10000; i++)
  1395.     {
  1396.       f (opponent, 2);
  1397.     }
  1398.   t2 = time (0);
  1399.   NodeCnt = 10000L * (TrPnt[3] - TrPnt[2]);
  1400.   evrate = NodeCnt / (t2 - t1);
  1401.   ShowNodeCnt (NodeCnt, evrate);
  1402. }
  1403.  
  1404. void
  1405. InputCommand (void)
  1406.  
  1407. /*
  1408.   Process the users command. If easy mode is OFF (the computer is thinking
  1409.   on opponents time) and the program is out of book, then make the 'hint'
  1410.   move on the board and call SelectMove() to find a response. The user
  1411.   terminates the search by entering ^C (quit siqnal) before entering a
  1412.   command. If the opponent does not make the hint move, then set Sdepth to
  1413.   zero.
  1414. */
  1415.  
  1416. {
  1417.   short ok, tmp;
  1418.   unsigned short mv;
  1419.   char s[80];
  1420.  
  1421.   ok = flag.quit = false;
  1422.   player = opponent;
  1423.   ShowSidetomove ();
  1424.   ft = 0;
  1425.   if (hint > 0 && !flag.easy && Book == NULL)
  1426.     {
  1427.       fflush (stdout);
  1428.       time0 = time ((long *) 0);
  1429.       algbr ((short) hint >> 8, (short) hint & 0xFF, false);
  1430.       strcpy (s, mvstr[0]);
  1431.       tmp = epsquare;
  1432.       if (VerifyMove (s, 1, &mv))
  1433.         {
  1434.           ShowPrompt ();
  1435.           SelectMove (computer, 2);
  1436.           (void) VerifyMove (mvstr[0], 2, &mv);
  1437.           if (Sdepth > 0)
  1438.             Sdepth--;
  1439.         }
  1440.       ft = time ((long *) 0) - time0;
  1441.       epsquare = tmp;
  1442.     }
  1443.   signal (SIGINT, Die);
  1444. #ifndef MSDOS
  1445.   signal (SIGQUIT, Die);
  1446. #endif /* MSDOS */
  1447.   while (!(ok || flag.quit))
  1448.     {
  1449.       ShowPrompt ();
  1450.       scanz ("%s", s);
  1451.       player = opponent;
  1452.       ok = VerifyMove (s, 0, &mv);
  1453.       if (ok && mv != hint)
  1454.         {
  1455.           Sdepth = 0;
  1456.           ft = 0;
  1457.         }
  1458.       if (*s == '\0')
  1459.         UpdateDisplay (0, 0, 1, 0);
  1460.       if (strcmp (s, "bd") == 0)
  1461.         {
  1462.           ClrScreen ();
  1463.           UpdateDisplay (0, 0, 1, 0);
  1464.         }
  1465.       if ((strcmp (s, "quit") == 0) || (strcmp (s, "exit") == 0))
  1466.         flag.quit = true;
  1467.       if (strcmp (s, "post") == 0)
  1468.         flag.post = !flag.post;
  1469.       if (strcmp (s, "edit") == 0)
  1470.         EditBoard ();
  1471.       if (strcmp (s, "go") == 0)
  1472.         ok = true;
  1473.       if (strcmp (s, "help") == 0)
  1474.         help ();
  1475.       if (strcmp (s, "force") == 0)
  1476.         flag.force = !flag.force;
  1477.       if (strcmp (s, "book") == 0)
  1478.         Book = NULL;
  1479.       if (strcmp (s, "undo") == 0 && GameCnt > 0)
  1480.         Undo ();
  1481.       if (strcmp (s, "new") == 0)
  1482.         NewGame ();
  1483.       if (strcmp (s, "list") == 0)
  1484.         ListGame ();
  1485.       if (strcmp (s, "level") == 0)
  1486.         SelectLevel ();
  1487.       if (strcmp (s, "hash") == 0)
  1488.         flag.hash = !flag.hash;
  1489.       if (strcmp (s, "beep") == 0)
  1490.         flag.beep = !flag.beep;
  1491.       if (strcmp (s, "Awindow") == 0)
  1492.         ChangeAlphaWindow ();
  1493.       if (strcmp (s, "Bwindow") == 0)
  1494.         ChangeBetaWindow ();
  1495.       if (strcmp (s, "hint") == 0)
  1496.         GiveHint ();
  1497.       if (strcmp (s, "both") == 0)
  1498.         {
  1499.           flag.bothsides = !flag.bothsides;
  1500.           Sdepth = 0;
  1501.           SelectMove (opponent, 1);
  1502.           ok = true;
  1503.         }
  1504.       if (strcmp (s, "reverse") == 0)
  1505.         {
  1506.           flag.reverse = !flag.reverse;
  1507.           ClrScreen ();
  1508.           UpdateDisplay (0, 0, 1, 0);
  1509.         }
  1510. #if !defined(MSDOS) || defined(SEVENBIT)
  1511.       if (strcmp (s, "shade") == 0)
  1512.         {
  1513.           shade = !shade;
  1514.           ClrScreen ();
  1515.           UpdateDisplay (0, 0, 1, 0);
  1516.         }
  1517. #endif /* MSDOS && !SEVENBIT */
  1518.       if (strcmp (s, "switch") == 0)
  1519.         {
  1520.           computer = otherside[computer];
  1521.           opponent = otherside[opponent];
  1522.           flag.force = false;
  1523.           Sdepth = 0;
  1524.           ok = true;
  1525.         }
  1526.       if (strcmp (s, "white") == 0)
  1527.         {
  1528.           computer = white;
  1529.           opponent = black;
  1530.           ok = true;
  1531.           flag.force = false;
  1532.           Sdepth = 0;
  1533.         }
  1534.       if (strcmp (s, "black") == 0)
  1535.         {
  1536.           computer = black;
  1537.           opponent = white;
  1538.           ok = true;
  1539.           flag.force = false;
  1540.           Sdepth = 0;
  1541.         }
  1542.       if (strcmp (s, "remove") == 0 && GameCnt > 1)
  1543.         {
  1544.           Undo ();
  1545.           Undo ();
  1546.         }
  1547.       if (strcmp (s, "get") == 0)
  1548.         GetGame ();
  1549.       if (strcmp (s, "save") == 0)
  1550.         SaveGame ();
  1551.       if (strcmp (s, "depth") == 0)
  1552.         ChangeSearchDepth ();
  1553.       if (strcmp (s, "random") == 0)
  1554.         dither = 6;
  1555.       if (strcmp (s, "easy") == 0)
  1556.         flag.easy = !flag.easy;
  1557.       if (strcmp (s, "contempt") == 0)
  1558.         SetContempt ();
  1559.       if (strcmp (s, "xwndw") == 0)
  1560.         ChangeXwindow ();
  1561.       if (strcmp (s, "coords") == 0)
  1562.         {
  1563.           coords = !coords;
  1564.           UpdateDisplay (0, 0, 1, 0);
  1565.         }
  1566. #if !defined(MSDOS) || defined(SEVENBIT)
  1567.       if (strcmp (s, "stars") == 0)
  1568.         {
  1569.           stars = !stars;
  1570.           UpdateDisplay (0, 0, 1, 0);
  1571.         }
  1572. #endif /* MSDOS && !SEVENBIT */
  1573.       if (strcmp (s, "test") == 0)
  1574.         {
  1575.           ShowMessage("Testing MoveList Speed");
  1576.           TestSpeed (MoveList);
  1577.           ShowMessage("Testing CaptureList Speed");
  1578.           TestSpeed (CaptureList);
  1579.         }
  1580.       if (strcmp (s, "p") == 0)
  1581.         ShowPostnValues ();
  1582.       if (strcmp (s, "debug") == 0)
  1583.         DoDebug ();
  1584.       if (strcmp (s, "rv") == 0)
  1585.         {
  1586.           rv = !rv;
  1587. #if !defined(MSDOS) || defined(SEVENBIT)
  1588.           shade = !rv;
  1589.           stars = !rv;
  1590. #endif /* MSDOS && !SEVENBIT */
  1591.           UpdateDisplay (0, 0, 1, 0);
  1592.         }
  1593.     }
  1594.  
  1595.   ClearMessage ();
  1596.   ElapsedTime (1);
  1597.   if (flag.force)
  1598.     {
  1599.       computer = opponent;
  1600.       opponent = otherside[computer];
  1601.     }
  1602.   signal (SIGINT, TerminateSearch);
  1603. #ifndef MSDOS
  1604.   signal (SIGQUIT, TerminateSearch);
  1605. #endif /* MSDOS */
  1606. }
  1607.